package com.yoi.Utils;


import com.yoi.bean.Constants;
import lombok.Data;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.connection.SimpleRoutingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;

import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;


@Configuration
public class MyRabbitMQConfig {

    /*@Bean
    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }*/
    @Data
    @Configuration
    @ConfigurationProperties(prefix = "spring.rabbitmq.test1")
    public class RabbitConfigTest1 {
        private String host;
        private int port;
        private String username;
        private String password;
        private String virtualhost;
    }

    @Data
    @Configuration
    @ConfigurationProperties(prefix = "spring.rabbitmq.test2")
    public class RabbitConfigTest2 {
        private String host;
        private int port;
        private String username;
        private String password;
        private String virtualhost;

    }

    @Data
    @Configuration
    @ConfigurationProperties(prefix = "spring.rabbitmq.test3")
    public class RabbitConfigTest3 {
        private String host;
        private int port;
        private String username;
        private String password;
        private String virtualhost;

    }

    //发送到交换器后接收ACK回调
    final RabbitTemplate.ConfirmCallback confirmCallback = new RabbitTemplate.ConfirmCallback() {
        @Override
        public void confirm(CorrelationData correlationData, boolean ack, String cause) {
            System.out.println("correlationDate:" + correlationData);
            String messageId = correlationData.getId();
            if (ack) {
                //brokerMessageLogMapper.changeBrokerMessageLogStatus(messageId,Constants.ORDER_SEND_SUCCESS);

            } else {
                System.out.println("异常处理");
            }
        }
    };
    //无相应队列与交换机绑定时的回调
    final RabbitTemplate.ReturnCallback returnCallback = new RabbitTemplate.ReturnCallback() {
        @Override
        public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {

        }
    };


    @Bean(name = "FirstConnectionFactory")

    public ConnectionFactory FirstConnectionFactory(RabbitConfigTest1 test1) {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(test1.host);
        connectionFactory.setPort(test1.port);
        connectionFactory.setUsername(test1.username);
        connectionFactory.setPassword(test1.password);
        connectionFactory.setVirtualHost(test1.virtualhost);
        return connectionFactory;
    }

    @Bean(name = "SecondConnectionFactory")
    @Primary
    public ConnectionFactory SecondConnectionFactory(RabbitConfigTest2 test1) {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(test1.host);
        connectionFactory.setPort(test1.port);
        connectionFactory.setUsername(test1.username);
        connectionFactory.setPassword(test1.password);
        connectionFactory.setVirtualHost(test1.virtualhost);
        return connectionFactory;
    }

    @Bean(name = "ThirdConnectionFactory")

    public ConnectionFactory ThirdConnectionFactory(RabbitConfigTest3 test1) {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(test1.host);
        connectionFactory.setPort(test1.port);
        connectionFactory.setUsername(test1.username);
        connectionFactory.setPassword(test1.password);
        connectionFactory.setVirtualHost(test1.virtualhost);
        return connectionFactory;
    }

    @Bean(name = "FirstRabbitTemplate")

    public RabbitTemplate firstRabbitTemplate(
            @Qualifier("FirstConnectionFactory") ConnectionFactory connectionFactory
    ) {
        RabbitTemplate hospSyncRabbitTemplate = new RabbitTemplate(connectionFactory);
        /*  hospSyncRabbitTemplate.setConfirmCallback(rabbitConfirmCallback);

         *//**
         * 当mandatory标志位设置为true时
         * 如果exchange根据自身类型和消息routingKey无法找到一个合适的queue存储消息
         * 那么broker会调用basic.return方法将消息返还给生产者
         * 当mandatory设置为false时，出现上述情况broker会直接将消息丢弃
         *//*
        hospSyncRabbitTemplate.setMandatory(true);
        hospSyncRabbitTemplate.setReturnCallback(rabbitReturnCallback);
        //使用单独的发送连接，避免生产者由于各种原因阻塞而导致消费者同样阻塞
        hospSyncRabbitTemplate.setUsePublisherConnection(true);*/

        return hospSyncRabbitTemplate;
    }

    @Bean(name = "SecondRabbitTemplate")
    @Primary
    public RabbitTemplate secondRabbitTemplate(
            @Qualifier("SecondConnectionFactory") ConnectionFactory connectionFactory
    ) {
        RabbitTemplate hPayRabbitTemplate = new RabbitTemplate(connectionFactory);
        //使用外部事物
        //lpzRabbitTemplate.setChannelTransacted(true);
        return hPayRabbitTemplate;
    }

    @Bean(name = "ThirdRabbitTemplate")
    public RabbitTemplate ThirdRabbitTemplate(
            @Qualifier("ThirdConnectionFactory") ConnectionFactory connectionFactory
    ) {
        RabbitTemplate hPayRabbitTemplate = new RabbitTemplate(connectionFactory);
        //使用外部事物
        //lpzRabbitTemplate.setChannelTransacted(true);
        return hPayRabbitTemplate;
    }

    @Bean(name = "FirstContainerFactory")
    public SimpleRabbitListenerContainerFactory FirstContainerFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            @Qualifier("FirstConnectionFactory") ConnectionFactory connectionFactory
    ) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    @Bean(name = "SecondContainerFactory")
    public SimpleRabbitListenerContainerFactory SecondContainerFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            @Qualifier("SecondConnectionFactory") ConnectionFactory connectionFactory
    ) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    @Bean(name = "ThirdContainerFactory")
    public SimpleRabbitListenerContainerFactory ThridContainerFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            @Qualifier("ThirdConnectionFactory") ConnectionFactory connectionFactory
    ) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }

}
    //两种生成Queue的模式：一种通过注解绑定自动生成，一种直接进行代码声明，包含Exchange也要声明
/*    @Bean
    @RabbitListener(bindings=@QueueBinding(value=@org.springframework.amqp.rabbit.annotation.Queue(value="hello1",durable="ture"),
            exchange=@Exchange(name="hello1",durable="true",type="topic"), key="order.*"))
    public Queue firstQueue() {
        System.out.println("configuration firstQueue ........................");
        return new Queue("hello1");
    }

    @Bean
    @RabbitListener(bindings=@QueueBinding(value=@org.springframework.amqp.rabbit.annotation.Queue(value="hello2",durable="ture"),
            exchange=@Exchange(name="hello2",durable="true",type="topic"), key="order.*"))
    public Object secondQueue() {
        System.out.println("configuration secondQueue ........................");
        return new Queue("hello2");
    }*/


